-- This class defines a buffer designed to store pointers to locations in the shared memory

Library ieee;
Use ieee.std_logic_1164.all;
Use work.transmit_package.all;

Entity FramePointerBuffer Is
	Port( switchIncomingFramePointer 		: In Std_logic;
		  switchFramePointer				: In Std_logic_vector(9 downto 0);
		  switchFull						: Out Std_logic; -- Make this valid everytime
		  Clock								: In Std_logic;
		  transmitInitialize				: In Std_logic;
		  transmitGetNextFramePointer		: In Std_logic;
		  transmitEmpty						: Out Std_logic; -- Make this valid everytime
		  transmitNextFramePointer			: Out Std_logic_vector(9 downto 0);
		  bufferFull						: Buffer Std_logic);
End FramePointerBuffer;

Architecture Behavior Of FramePointerBuffer Is
Constant Zeros	: Std_logic_vector(9 downto 0) := "0000000000";

-- These act as pointers to the front and back of the array, they will contain at most a single bit of 1 in a given location
Signal pointer_to_back	: Std_logic_vector(16 downto 0);
Signal MoveAll			: Std_logic;
Signal NewPointer		: Std_logic;
--Signal GetPointer		: Std_logic;
Signal moveBack			: Std_logic;

Type vectorArray Is Array(14 downto 0) Of Std_logic_vector(9 downto 0);
Signal addrmove			: vectorArray;


Begin
	Process
	Begin
		Wait Until Clock'Event And Clock = '1';
		
		If transmitInitialize = '1' Then
			pointer_to_back <= "00000000000000001";
			MoveAll <= '0';
			NewPointer <= '0';
			--NewPointerNext <= '0';
			--GetPointer <= '0';
			--GetPointerNext <= '0';
			moveBack <= '0';
			bufferFull <= '0';
		End If;
		
		If switchIncomingFramePointer = '1' And bufferFull = '0' Then
			NewPointer <= '1';
			moveBack <= '1';
		Else
			NewPointer <= '0';
			moveBack <= '0';
		End If;	
		
		If transmitGetNextFramePointer = '1' Then
			--GetPointer <= '1';
			pointer_to_back <= forward(pointer_to_back);
			MoveAll <= '1';
		Else
			--GetPointer <= '0';
			MoveAll <= '0';
		End If;
		
		If moveBack = '1' Then
			pointer_to_back <= backward(pointer_to_back);
		End If;
		
		If pointer_to_back = "10000000000000000" Then
			bufferFull <= '1';
		Else
			bufferFull <= '0';
		End If;
		
		switchFull <= bufferFull;
		
		If pointer_to_back = "00000000000000001" Then
			transmitEmpty <= '1';
		Else
			transmitEmpty <= '0';
		End If;
				
	End Process;
	frame0: framepointer Port Map(addrmove(0), Clock, MoveAll, pointer_to_back(0) And NewPointer, switchFramePointer, transmitNextFramePointer);
	frame_pointer_array: For i In 1 To 14 Generate
	Begin	
		frame: framepointer Port Map(addrmove(i), Clock, MoveAll, pointer_to_back(i) And NewPointer, switchFramePointer,  addrmove(i-1));
	End Generate frame_pointer_array;
	frame15: framepointer Port Map(Zeros, Clock, MoveAll, pointer_to_back(15) And NewPointer, switchFramePointer, addrmove(14)); 
End Behavior;